package com.yk.system.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yk.api.system.dto.ConfigurationRoleDTO;
import com.yk.common.core.constant.CacheConstants;
import com.yk.common.core.constant.NumberConstant;
import com.yk.common.core.enums.DeviceRoleStatusEnum;
import com.yk.common.core.enums.RoleTypeEnum;
import com.yk.common.core.exception.ServiceException;
import com.yk.common.core.utils.LoginHelper;
import com.yk.common.redis.service.RedisService;
import com.yk.system.entity.Configuration;
import com.yk.system.entity.ConfigurationRole;
import com.yk.system.entity.User;
import com.yk.system.mapper.ConfigurationMapper;
import com.yk.system.mapper.ConfigurationRoleMapper;
import com.yk.system.mapper.UserMapper;
import com.yk.system.service.ConfigurationRoleService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 组态权限表 服务类
 *
 * @author lmx
 * @since 2024-04-24
 */
@Service
@RequiredArgsConstructor
public class ConfigurationRoleServiceImpl extends ServiceImpl<ConfigurationRoleMapper, ConfigurationRole>
        implements ConfigurationRoleService {

    private final RedisService redisService;
    private final UserMapper userMapper;
    private final ConfigurationMapper configurationMapper;

    @Override
    public void checkShare(Long configurationId, String message, Long userId) {
        LambdaQueryWrapper<ConfigurationRole> lambda = new LambdaQueryWrapper<>();
        lambda.eq(ConfigurationRole::getUserId, userId);
        lambda.eq(ConfigurationRole::getConfigurationId, configurationId);
        lambda.eq(ConfigurationRole::getStatus, NumberConstant.ZERO_STR);
        ConfigurationRole configurationRole = baseMapper.selectOne(lambda);
        Assert.isNull(configurationRole, message);
    }

    @Override
    public ConfigurationRole getByIdIgnoreDel(Long id) {
        return baseMapper.getByIdIgnoreDel(id);
    }

    @Override
    public void updateDelConfigurationRole(ConfigurationRole configurationRole) {
        baseMapper.updateById2Del(configurationRole);
        // 计算过期时间
        Date dateTime = DateUtil.parseDateTime("9999-12-31 00:00:00");
        if (Objects.nonNull(configurationRole.getExpiredTime()) &&
                !DateUtil.isSameDay(dateTime, configurationRole.getExpiredTime())) {
            Date expiredTime = configurationRole.getExpiredTime();
            long time = DateUtil.between(new Date(), expiredTime, DateUnit.MINUTE);
            redisService.setCacheObject(CacheConstants.CONFIGURATION_ROLE_EXPIRED_TIME_KEY + configurationRole.getId(),
                    configurationRole.getId(), time, TimeUnit.MINUTES);
        }
    }

    @Override
    public void updateConfigurationRole(ConfigurationRole configurationRole) {
        // 计算过期时间
        Date dateTime = DateUtil.parseDateTime("9999-12-31 00:00:00");
        if (Objects.nonNull(configurationRole.getExpiredTime()) &&
                !DateUtil.isSameDay(dateTime, configurationRole.getExpiredTime())) {
            Date expiredTime = configurationRole.getExpiredTime();
            long time = DateUtil.between(new Date(), expiredTime, DateUnit.MINUTE);
            redisService.setCacheObject(CacheConstants.CONFIGURATION_ROLE_EXPIRED_TIME_KEY + configurationRole.getId(),
                    configurationRole.getId(), time, TimeUnit.MINUTES);
        }
        baseMapper.updateById(configurationRole);
    }

    @Override
    public ConfigurationRole getConfigurationRole(Long configurationId) {
        Long loginUserId = LoginHelper.getLoginUserId();
        LambdaQueryWrapper<ConfigurationRole> lambda = new LambdaQueryWrapper<>();
        lambda.eq(ConfigurationRole::getUserId, loginUserId);
        lambda.eq(ConfigurationRole::getConfigurationId, configurationId);
        lambda.eq(ConfigurationRole::getStatus, NumberConstant.ZERO_STR);
        return baseMapper.selectOne(lambda);
    }

    @Override
    public void assignConfigurationRole(ConfigurationRoleDTO dto) {
        if (Objects.isNull(dto)) {
            return;
        }
        if (Objects.nonNull(dto.getUserId())) {
            User user = userMapper.selectById(dto.getUserId());
            if (Objects.nonNull(user)) {
                dto.setUserName(user.getNickName());
                dto.setPhone(user.getPhone());
            }
        }
        Date dateTime = DateUtil.parseDateTime("9999-12-31 00:00:00");
        if (Objects.nonNull(dto.getExpiredTime()) &&
                DateUtil.isSameDay(dateTime, dto.getExpiredTime())) {
            dto.setExpiredTime(null);
        }
        Configuration configuration = configurationMapper.selectById(dto.getConfigurationId());
        if (Objects.nonNull(configuration)){
            dto.setConfigurationName(configuration.getName());
        }
    }

    @Override
    public void update2Status(String id) {
        ConfigurationRole configurationRole = baseMapper.selectById(id);
        if (Objects.nonNull(configurationRole)) {
            configurationRole.setStatus(NumberConstant.ONE_STR);
            baseMapper.updateById(configurationRole);
        }
    }

    @Override
    public ConfigurationRole initConfigurationRole(long configurationId) {
        Long loginUserId = LoginHelper.getLoginUserId();
        ConfigurationRole configurationRole = new ConfigurationRole();
        configurationRole.setConfigurationId(configurationId);
        configurationRole.setAdminId(loginUserId);
        configurationRole.setUserId(loginUserId);
        configurationRole.setRoleType(RoleTypeEnum.ADMIN.getCode());
        configurationRole.setStatus(DeviceRoleStatusEnum.SHARING.getCode());
        return configurationRole;
    }

    @Override
    public void saveDeviceRole(ConfigurationRole configurationRole) {
        long id = IdWorker.getId();
        configurationRole.setId(id);
        Date now = new Date();
        if (Objects.nonNull(configurationRole.getExpiredTime())) {
            if (now.after(configurationRole.getExpiredTime())) {
                throw new ServiceException("不能选择已过期的时间");
            }
            // 计算过期时间
            Date dateTime = DateUtil.parseDateTime("9999-12-31 00:00:00");
            if (Objects.nonNull(configurationRole.getExpiredTime()) &&
                    !DateUtil.isSameDay(dateTime, configurationRole.getExpiredTime())) {
                Date expiredTime = configurationRole.getExpiredTime();
                long time = DateUtil.between(now, expiredTime, DateUnit.MINUTE);
                redisService.setCacheObject(CacheConstants.CONFIGURATION_ROLE_EXPIRED_TIME_KEY + id, id, time, TimeUnit.MINUTES);
            }
        }
        baseMapper.insert(configurationRole);
    }

    @Override
    public List<ConfigurationRoleDTO> selectRole2Device() {
        return baseMapper.selectRole2Device(LoginHelper.getLoginUserId());
    }
}